package com.hntx.joymusic.mediaplayer;

import android.media.MediaPlayer;
import android.media.TimedText;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.io.IOException;

public class MPlayer implements MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnCompletionListener, MediaPlayer.OnVideoSizeChangedListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener,
        MediaPlayer.OnErrorListener, SurfaceHolder.Callback, MediaPlayer.OnInfoListener {

    private MediaPlayer player;
    private String source;

    private SurfaceHolder surfaceHolder;
    private SurfaceView mSurfaceView;
    private IMPlayListener mPlayListener;
    private IMPlayerPrepared imPlayerPrepared;
    private ISeekCompleted iSeekCompleted;
    private IMPlayerSurfaceDestroyed imPlayerSurfaceDestroyed;
    private IMPlayerBufferUpdate imPlayerBufferUpdate;


    public MPlayer() {
    }

    private IMInfoListener imInfoListener;

    public void setMediaInfoListener(IMInfoListener imInfoListener) {
        this.imInfoListener = imInfoListener;
    }

    public void setImgSurfaceGone() {
        if (mSurfaceView != null) {
            mSurfaceView.setVisibility(View.GONE);
        }
    }

    public interface IMInfoListener {
        boolean onMediaInfo(MediaPlayer mediaPlayer, int i, int i1);
    }

    public interface IMPlayerPrepared {
        void onMPlayerPrepare();
    }

    public interface ISeekCompleted {
        void onSeekCompleted();
    }

    public interface IMPlayerSurfaceDestroyed {
        void onSurfaceDestroyed();
    }

    public interface IMPlayerBufferUpdate {
        void onBufferUpdate(int percent);
    }

    public void setImPlayerBufferUpdate(IMPlayerBufferUpdate onPlayerBufferUpdate) {
        this.imPlayerBufferUpdate = onPlayerBufferUpdate;
    }

    public void setOnPrepared(IMPlayerPrepared onPrepare) {
        this.imPlayerPrepared = onPrepare;
    }

    public void setiSeekCompleted(ISeekCompleted onSeekCompleted) {
        this.iSeekCompleted = onSeekCompleted;
    }

    public void setiSurfaceDestroyed(IMPlayerSurfaceDestroyed onSurfaceDestroyed) {
        this.imPlayerSurfaceDestroyed = onSurfaceDestroyed;
    }

    private void createPlayerIfNeed() {
        if (null == player) {
            player = new MediaPlayer();
            player.setScreenOnWhilePlaying(true);
            player.setOnBufferingUpdateListener(this);
            player.setOnVideoSizeChangedListener(this);
            player.setOnCompletionListener(this);
            player.setOnPreparedListener(this);
            player.setOnSeekCompleteListener(this);
            player.setOnErrorListener(this);
            player.setOnInfoListener(this);
        }
    }

    public void seekto(int msec) {
        if (player != null)
            player.seekTo(msec);
    }

    public int getDuration() {
        int tmp = 0;
        try {
            tmp = player.getDuration();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tmp;
    }

    public int getCurrentPosition() {
        int pos = -1;
        if (player != null && isPrepared) {
            try {
                pos = player.getCurrentPosition();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return pos;
    }

    public void setPlayListener(IMPlayListener listener) {
        this.mPlayListener = listener;
    }

    /**
     * 视频状态
     *
     * @return 视频是否正在播放
     */
    public boolean isPlaying() {
        boolean flag = false;
        try {
            flag = player != null && player.isPlaying();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public void setDisplay(SurfaceView surfaceView) {
        if (this.surfaceHolder != null) {
            this.surfaceHolder.removeCallback(this);
            this.surfaceHolder = null;
        }
        this.mSurfaceView = surfaceView;
        this.surfaceHolder = surfaceView.getHolder();
        this.surfaceHolder.addCallback(this);
    }

    public void onDestroy() {
        /**2019.1.31 增加状态 防止在不正确的状态去获取数据*/
        isPrepared = false;
        if (player != null && player.isPlaying()) {
            player.stop();
            player.release();
            player = null;
        }
    }

    @Override
    public boolean onInfo(MediaPlayer mediaPlayer, int arg1, int arg2) {
        if (imInfoListener != null) {
            return imInfoListener.onMediaInfo(mediaPlayer, arg1, arg2);
        }
        return false;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        if (imPlayerBufferUpdate != null)
            imPlayerBufferUpdate.onBufferUpdate(percent);
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        /**2019.1.30 guo surface销毁问题*/
        if (mSurfaceView != null) {
            mSurfaceView.setVisibility(View.GONE);
        }
        onDestroy();
        if (mPlayListener != null) {
            mPlayListener.onComplete(this);
        }
    }

    public void onResume() {

        Log.i(TAG, "onResume: ");
        if (player != null) {
            try {
                player.start();
                if (mPlayListener != null) {
                    mPlayListener.onResume(this);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void onPause() {
        if (player != null && player.isPlaying()) {
            player.pause();
            if (mPlayListener != null) {
                mPlayListener.onPause(this);
            }
        }
    }

    public void setSelectTrack(int index) {
        try {
            player.selectTrack(index);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void deselectTrack(int index) {
        try {
            player.deselectTrack(index);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public MediaPlayer.TrackInfo[] getTrackInfo() {
        if (mtInfo != null) {
            return mtInfo;
        } else {
            return null;
        }
    }

    private MediaPlayer.TrackInfo[] mtInfo = null;
    /**
     * 2019.1.31 增加状态 防止在不正确的状态去获取数据
     */
    private boolean isPrepared = false;

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.e(TAG, "onPrepared");
        try {
            mtInfo = player.getTrackInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }
        /**2019.1.31 增加状态 防止在不正确的状态去获取数据*/
        isPrepared = true;
        player.setOnTimedTextListener((mediaPlayer, timedText) -> {
            if (onTimedMPTextListener != null) {
                onTimedMPTextListener.setOnTimeMpTextListener(mediaPlayer, timedText);
            }
        });
        if (imPlayerPrepared != null)
            imPlayerPrepared.onMPlayerPrepare();
//        if (surfaceHolder == null) return;
        if (surfaceHolder != null)
            player.setDisplay(surfaceHolder);
        Log.e(TAG, "player.start()");
        player.start();
        if (mPlayListener != null) {
            mPlayListener.onStart(this);
        }
        if (currentPosition > 0) {
            player.seekTo(currentPosition);
            if (!isPlay) {
                player.pause();
            }
        }
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        if (onVideoChangedListener != null) {
            boolean flag = false;
            if (height <= 1080 && height > 1000) {
                flag = true;
            }
            if (height >= 800 && height < 900) {
                flag = false;
            }
            onVideoChangedListener.OnVideoChanged(flag);
        }

        if (width > 0 && height > 0) {
            tryResetSurfaceSize(mSurfaceView, width, height);
        }
    }

    @Override
    public void onSeekComplete(MediaPlayer mp) {
        if (iSeekCompleted != null)
            iSeekCompleted.onSeekCompleted();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mp.reset();
        if (mPlayListener != null) {
            mPlayListener.onError(source, what, extra);
        }
        return false;
    }

    private int currentPosition = 0;
    public static final String TAG = "MediaPlayerLogs";

    public void setSource(String url) {
        this.source = url;
        currentPosition = 0;
        createPlayerIfNeed();
        /**2019.1.30 guo 防止surface播放完上一部视频，界面没有被销毁。*/
        if (mSurfaceView != null) {
            isCreated = false;
            if (mSurfaceView.getVisibility() != View.VISIBLE)
                mSurfaceView.setVisibility(View.VISIBLE);
            Log.e(TAG, "mSurfaceView!=NULL");
        }
        Log.e(TAG, "setSource");
    }

    private void playVideo() {
        Log.e(TAG, "playVideo");
        if (isCreated) {
            try {
                if (TextUtils.isEmpty(source)) {
                    return;
                }
                player.reset();
                player.setDataSource(source);
                player.prepareAsync();
                Log.e(TAG, "prepareAsync");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void start() {
        try {
            if (TextUtils.isEmpty(source)) {
                return;
            }
            player.setDataSource(source);
            player.prepareAsync();
            player.start();
            Log.e(TAG, "prepareAsync");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (surfaceHolder != null) {
            createPlayerIfNeed();
            isCreated = true;
            player.setDisplay(surfaceHolder);
            Log.e(TAG, "surfaceCreated");
            playVideo();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    private boolean isCreated = false;
    private boolean isPlay = true;

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        /**2019.5.8 修改，因为暂停状态导致的问题*/
        if (player != null) {
            if (player.getCurrentPosition() > 0) {
                currentPosition = player.getCurrentPosition();
            }
            if (player.isPlaying()) {
                player.stop();
                isPlay = true;
            } else {
                isPlay = false;
            }
            player.release();
            player = null;
            isCreated = false;
            if (imPlayerSurfaceDestroyed != null)
                imPlayerSurfaceDestroyed.onSurfaceDestroyed();
        }
    }

    public void setOnTimedMPTextListener(OnTimedMPTextListener onTimedMPTextListener) {
        this.onTimedMPTextListener = onTimedMPTextListener;
    }

    OnTimedMPTextListener onTimedMPTextListener;

    public interface OnTimedMPTextListener {
        void setOnTimeMpTextListener(MediaPlayer mediaPlayer, TimedText timedText);
    }

    OnVideoChangedListener onVideoChangedListener;

    public interface OnVideoChangedListener {
        void OnVideoChanged(boolean flag);
    }

    public void setOnVideoChangedListener(OnVideoChangedListener onVideoChangedListener) {
        this.onVideoChangedListener = onVideoChangedListener;
    }

    private boolean mIsCrop = false;

    //根据设置和视频尺寸，调整视频播放区域的大小
    private void tryResetSurfaceSize(final View view, int videoWidth, int videoHeight) {
        ViewGroup parent = (ViewGroup) view.getParent();
        int width = parent.getWidth();
        int height = parent.getHeight();
        if (width > 0 && height > 0) {
            final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
            if (mIsCrop) {
                float scaleVideo = videoWidth / (float) videoHeight;
                float scaleSurface = width / (float) height;
                if (scaleVideo < scaleSurface) {
                    params.width = width;
                    params.height = (int) (width / scaleVideo);
                    params.setMargins(0, (height - params.height) / 2, 0, (height - params.height) / 2);
                } else {
                    params.height = height;
                    params.width = (int) (height * scaleVideo);
                    params.setMargins((width - params.width) / 2, 0, (width - params.width) / 2, 0);
                }
            } else {
                float scaleVideo = videoWidth / (float) videoHeight;
                float scaleSurface = width / (float) height;
                if (scaleVideo > scaleSurface) {
                    params.width = width;
                    params.height = (int) (width / scaleVideo);
                    params.setMargins(0, (height - params.height) / 2, 0, (height - params.height) / 2);
                } else {
                    params.height = height;
                    params.width = (int) (height * scaleVideo);
                    params.setMargins((width - params.width) / 2, 0, (width - params.width) / 2, 0);
                }
            }
            view.setLayoutParams(params);
        }
    }
}
